﻿using System;
using System.Runtime.Serialization;
using System.Windows;
using System.Windows.Ink;
using ThePresenter.Windows.Controls;
using System.Windows.Controls;


namespace ThePresenter.Polls.Data
{
	[Serializable]
	public class CanvasQuestionData : QuestionData, ISerializable
	{
		#region Fields
		/// <summary>
		/// The size.
		/// </summary>
		Size _Size;

		/// <summary>
		/// The background.
		/// </summary>
		byte[] _Background;

		/// <summary>
		/// The strokes.
		/// </summary>
		StrokeCollection _Strokes;
		#endregion


		#region Properties
		/// <summary>
		/// Gets or sets the size.
		/// </summary>
		/// <value>The size.</value>
		public Size Size
		{
			get
			{
				return _Size;
			}
			set
			{
				if (value != _Size)
				{
					_Size = value;
					OnPropertyChanged("Size");
				}
			}
		}

		/// <summary>
		/// Gets or sets the background.
		/// </summary>
		/// <value>The background.</value>
		public byte[] Background
		{
			get
			{
				return _Background;
			}
			set
			{
				if (value != _Background)
				{
					_Background = value;
					OnPropertyChanged("Background");
				}
			}
		}

		/// <summary>
		/// Gets or sets the strokes.
		/// </summary>
		/// <value>The strokes.</value>
		public StrokeCollection Strokes
		{
			get
			{
				if (_Strokes == null)
				{
					_Strokes = new StrokeCollection();
					//(_Strokes as INotifyCollectionChanged).CollectionChanged +=new NotifyCollectionChangedEventHandler((s, e) => this.OnPropertyChanged("Strokes"));
				}

				return _Strokes;
			}
			set
			{
				if (value != _Strokes)
				{
					_Strokes = value;
					OnPropertyChanged("Strokes");
				}
			}
		}
		#endregion


		#region Constructors
		/// <summary>
		/// Initializes a new instance of the <see cref="CanvasQuestionData"/> class.
		/// </summary>
		public CanvasQuestionData()
		{
			this.QuestionType = Polls.QuestionType.Canvas;
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="CanvasQuestionData"/> class.
		/// </summary>
		/// <param name="Source">The source.</param>
		public CanvasQuestionData(Slide Source) : this()
		{
			this.Fill(Source);
		}
		#endregion


		#region ISerializable Members
		/// <summary>
		/// Initializes a new instance of the <see cref="CanvasQuestionData"/> class.
		/// </summary>
		/// <param name="info">The info.</param>
		/// <param name="context">The context.</param>
		public CanvasQuestionData(SerializationInfo info, StreamingContext context)
		{
			Size = (Size)info.GetValue("Size", typeof(Size));
			Background = (byte[])info.GetValue("Background", typeof(byte[]));
			Strokes = ((byte[])info.GetValue("Strokes", typeof(byte[]))).ToStrokes();
			Question = (String)info.GetValue("Question", typeof(String));
			QuestionType = (QuestionType)info.GetValue("QuestionType", typeof(QuestionType));
		}

		/// <summary>
		/// Populates a <see cref="T:System.Runtime.Serialization.SerializationInfo"/> with the data needed to serialize the target object.
		/// </summary>
		/// <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"/> to populate with data.</param>
		/// <param name="context">The destination (see <see cref="T:System.Runtime.Serialization.StreamingContext"/>) for this serialization.</param>
		/// <exception cref="T:System.Security.SecurityException">The caller does not have the required permission. </exception>
		public void GetObjectData(SerializationInfo info, StreamingContext context)
		{
			info.AddValue("Size", Size, typeof(Size));
			info.AddValue("Background", Background, typeof(byte[]));
			info.AddValue("Strokes", Strokes.ToBytes(), typeof(byte[]));
			info.AddValue("Question", Question, typeof(String));
			info.AddValue("QuestionType", QuestionType, typeof(QuestionType));
		}
		#endregion


		#region Methods
		/// <summary>
		/// Fills data based on given slide.
		/// </summary>
		/// <param name="Source">The slide.</param>
		internal void Fill(Slide Source)
		{
			Strokes = (StrokeCollection)Source.Canvas.Dispatcher.Invoke(new Func<StrokeCollection>(() => Source.Canvas.Strokes.Clone()));
			Background = (byte[])Source.Canvas.Dispatcher.Invoke(new Func<byte[]>(() => Source.Canvas.GetBackground())); ;
			Size = Source.Size;
		}

		public Slide GetSlide()
		{
			Slide S = new Slide();

			S.Canvas = new InkCanvas();
			S.Canvas.SetBackground(Background);
			S.Canvas.Strokes = Strokes;
			S.Size = Size;

			return S;
		}
		#endregion
	}
}
